package com.bootdo.app.common.Interceptor;

import com.bootdo.app.common.annotion.IgnoreUserToken;
import com.bootdo.app.common.aop.exception.JWTAuthException;
import com.bootdo.app.common.config.AuthConfig;
import com.bootdo.app.common.constants.JWTConstants;
import com.bootdo.app.common.jwt.IJWTInfo;
import com.bootdo.app.common.utils.ContextHandlerUtil;
import com.bootdo.app.common.utils.JWTUtil;
import com.bootdo.app.common.utils.StringUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
  * @auther: Along
  * @description: token 验证拦截器
  */
public class TokenInterceptor extends HandlerInterceptorAdapter{

    @Autowired
    private AuthConfig authConfig;
//    @Autowired
//    private RedisTemplate<String,String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 将handler对象转换成HandlerMethod（请求方法）对象
        HandlerMethod handlerMethod = (HandlerMethod)handler;

        // 配置IgnoreUserToken注解说明不进行拦截
        IgnoreUserToken annotation = handlerMethod.getBeanType().getAnnotation(IgnoreUserToken.class);
        if(annotation == null){
            annotation = handlerMethod.getMethodAnnotation(IgnoreUserToken.class);
        }
        // 放行
        if(annotation != null){
            return super.preHandle(request, response, handler);
        }
        // 拦截
        String token = request.getHeader(authConfig.getTokenHeader());// 获取头信息
        if (StringUtils.isEmpty(token)) {
            if (request.getCookies() != null) {
                for (Cookie cookie : request.getCookies()) {
                    if (cookie.getName().equals(authConfig.getTokenHeader())) {
                        token = cookie.getValue();
                    }
                }
            }
        }
        try {
            IJWTInfo ijwtInfo = JWTUtil.getInfoFromToken(token, authConfig.getPubKeyByte());
//            if(ijwtInfo.getName().equals(JWTConstants.JWT_NAME_ADMIN)){// admin
//                String key = JWTConstants.JWT_AUTH_LOGIN_VERSION_KEY + JWTConstants.JWT_NAME_ADMIN;
//                String value = String.valueOf(redisTemplate.opsForHash().get(key, ijwtInfo.getUserId()+""));
//                if(StringUtils.isEmpty(value)){
//                    throw new JWTAuthException(JWTConstants.TOKEN_EXPIRED_ERR,JWTConstants.TOKEN_EXPIRED_MSG);
//                }
//                if(!value.equals(ijwtInfo.getUniqueName())){
//                    throw new JWTAuthException(JWTConstants.REPEAT_LOGIN_ERR,JWTConstants.REPEAT_LOGIN_MSG);
//                }
//            }else if(ijwtInfo.getName().equals(JWTConstants.JWT_NAME_USER)){
//                String value = (String)redisTemplate.opsForHash().get(JWTConstants.JWT_AUTH_LOGIN_VERSION_KEY, ijwtInfo.getUserId()+"");
//                if(value == null){
//                    throw new JWTAuthException(JWTConstants.TOKEN_EXPIRED_ERR,JWTConstants.TOKEN_EXPIRED_MSG);
//                }
//                if(!value.equals(ijwtInfo.getUniqueName())){
//                    throw new JWTAuthException(JWTConstants.REPEAT_LOGIN_ERR,JWTConstants.REPEAT_LOGIN_MSG);
//                }
//            }else{ // err
//                throw new JWTAuthException(JWTConstants.TOKEN_ERR,JWTConstants.TOKEN_ERR_MSG);
//            }
            ContextHandlerUtil.setCurrentUserId(ijwtInfo.getUserId());
            ContextHandlerUtil.setCurrentUserToken(token);
            ContextHandlerUtil.setOpenId(ijwtInfo.getOpenId());
            ContextHandlerUtil.setSessionKey(ijwtInfo.getUserSessionKey());
            ContextHandlerUtil.setSID(ijwtInfo.getUserSID());
        }catch (ExpiredJwtException ex){
            throw new JWTAuthException(JWTConstants.TOKEN_EXPIRED_ERR,JWTConstants.TOKEN_EXPIRED_MSG);
        }catch (UnsupportedJwtException ex){// token 格式错误
            throw new JWTAuthException(JWTConstants.TOKEN_FORMAT_WRONG_ERR,JWTConstants.TOKEN_FORMAT_WRONG_MSG);
        }catch (SignatureException ex){
            throw new JWTAuthException(JWTConstants.TOKEN_SIGNATURE_ERR,JWTConstants.TOKEN_SIGNATURE_MSG);
        }catch (IllegalArgumentException ex){
            throw new JWTAuthException(JWTConstants.TOKEN_EMPTY_ERR,JWTConstants.TOKEN_EMPTY_MSG);
        }
        return super.preHandle(request, response, handler);

    }
}
